package com.planw.beetl.sql.search;

import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.QueryExecutorBase;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiTypeParameterListOwner;
import com.intellij.util.Processor;
import com.intellij.util.QueryParameters;
import com.planw.beetl.service.BeetlMapperService;
import com.planw.beetl.service.BeetlSqlService;
import java.util.Map;
import org.jetbrains.annotations.NotNull;

/**
 * 通过Ctrl+左键点击mapper方法跳转md文件
 */
public class BeetlSqlJavaMapperQueryExecutorBase extends
    QueryExecutorBase<PsiElement, QueryParameters> {

  private static final Logger logger = Logger.getInstance(BeetlSqlJavaMapperQueryExecutorBase.class);


  protected void toSearchSql(PsiClass psiClass, PsiMethod psiMethod,
      Processor<? super PsiElement> consumer) {

    Project project = psiClass.getProject();
    BeetlSqlService beetlSqlService = BeetlSqlService.getInstance(project);
    BeetlMapperService beetlMapperService = BeetlMapperService.getInstance(project);
    if (!beetlMapperService.isBeetlMapper(psiClass)) {
      return;
    }

    PsiFile sqlFile = beetlMapperService.findSqlFile(psiClass);

    if (sqlFile == null) {
      return;
    }

    Map<PsiMethod, PsiElement> methodAndSqlIdMap = beetlMapperService.getMethodAndSqlIdMap(sqlFile,
        psiClass, psiMethod);
    PsiElement psiElement = methodAndSqlIdMap.get(psiMethod);
    if (psiElement != null) {
      consumer.process(psiElement);
    }
  }

  @Override
  public void processQuery(@NotNull QueryParameters queryParameters,
      @NotNull Processor<? super PsiElement> consumer) {

    if (!(queryParameters instanceof PsiTypeParameterListOwner)) {
      return;
    }
    if (!(queryParameters instanceof PsiMethod)) {
      return;
    }
    final Application application = ApplicationManager.getApplication();

    application.runReadAction(() -> {
      PsiMethod psiMethod = (PsiMethod) queryParameters;
      PsiClass psiClass = psiMethod.getContainingClass();
      if (null == psiClass) {
        return;
      }
      toSearchSql(psiClass, psiMethod, consumer);
    });
  }

}
